﻿Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Public Class ObjektEinheit3D
    Public Class EinheitInstanz
        Public Mesh As Objekt3DAnim
        Public EinheitID As String
        Public Kaputt As Boolean = False
        Public Dateiname As String
    End Class
    Shared Einheiten() As EinheitInstanz = {}
    Shared NichtEinheit As EinheitInstanz

    Public Sub IniEinheiten()
        Dim EStack As New Stack(Of EinheitInstanz)
        For Each Dat In My.Computer.FileSystem.GetFiles(DataSettings.Resourcenpfad + "Units\Overworld\3D\")
            If Dat.ToLower.EndsWith(".X".ToLower) Then
                'Hoffentlich ein gueltiges Format, und kein unnuetzes Gebaeude!
                Dim E As New EinheitInstanz
                E.Dateiname = Dat
                E.EinheitID = Dat.Remove(0, Dat.LastIndexOf("\") + 1).ToUpper.Replace(".X".ToUpper, "")
                E.Mesh = New Objekt3DAnim()
                E.Mesh.MeshBildLaden(Dat)
                E.Kaputt = False
                If Dat.ToLower.EndsWith("\Box.X".ToLower) Then
                    'cool, meine Nicht-Einheit ist da.
                    NichtEinheit = E
                Else
                    EStack.Push(E)
                End If
            End If
        Next
        Einheiten = EStack.ToArray
        'Array.Reverse(Einheiten)'nur, damit die Reihenfolge wieder stimmt!
        EStack.Clear() 'brauchen wir nicht mehr.
    End Sub
    Public Function getPos(ByVal X As Single, ByVal Y As Single, ByVal Einheit As ObjektEinheit, ByVal Schlacht As Integer) As Vector3
        Dim posVec As Vector3 = Objektverwalter.LandschaftenBilder(Objektverwalter.Spielfeld.Landschaften(X, Y, Schlacht).ID).getFigurPos(Einheit.GetFigurPos)
        posVec.X += X
        posVec.Z -= Y
        Return posVec
    End Function
    Public Sub Malen(ByVal Einheit As ObjektEinheit, ByVal X As Single, ByVal Y As Single, ByVal Schlacht As Integer, ByVal Spieler As Integer, ByVal Rotation As Single, ByVal Bewegt As Boolean, ByRef AnimC As AnimationController, ByVal AnimPeriode As Double, Optional ByVal HoehenVerschiebung As Single = 0) ' ByVal AnimSetName As String, ByRef AnimPos As Double, ByRef AnimPeriode As Double)

        Dim E As EinheitInstanz = getEinheit(Einheit.EinheitenID)
        If E.Mesh IsNot Nothing Then

            Dim standardMatrix As Matrix = Grafikengine.Grafikkarte.Transform.World


            Dim posVec As Vector3 = Objektverwalter.LandschaftenBilder(Objektverwalter.Spielfeld.Landschaften(CInt(X), CInt(Y), Schlacht).ID).getFigurPos(Einheit.GetFigurPos)
            Dim M As Matrix = Matrix.RotationY(Rotation)

            M.M41 = X + posVec.X
            M.M42 = posVec.Y + HoehenVerschiebung
            M.M43 = -(Y - posVec.Z)
            Grafikengine.Grafikkarte.Transform.World = M
            Dim Eingef As Boolean
            Dim Grundfarbe As Color = Objekt3D.Spielerfarben(Spieler)
            If Bewegt Then 'Wenn die Einheit schon gezogen hat, ist alles etwas dunkler
                Grundfarbe = ObjektmarkiertesFeld.getMischfarbe(Grundfarbe, Color.FromArgb(255, 0, 0, 0), 0.4)
            End If
            Objekt3D.SpielerFarbe = ObjektmarkiertesFeld.getFeldFarbe(X, Y, Grundfarbe, Eingef) 'eventuell muss die Einheit aber auch aufleuchten, wenn es ein markiertes feld ist.

            E.Mesh.ProcessNextFrame(M, AnimC, AnimPeriode)
            If Not E.Mesh.MalenAni(M, AnimC, DataSettings.TotalEinfaerben Or Eingef) Then
                'Fehler?
                AnimC = E.Mesh.getNewAnimationC
            End If
            'If Not E.Mesh.MalenAni(M, AnimSetName, AnimPos, DataSettings.TotalEinfaerben Or Eingef, AnimPeriode) Then
            '    'Fehler?
            '    E.Kaputt = True 'Theoretisch koennten wir ja die "Kaputten Animationen" auch einfach statisch malen, oder? ist sogar noch besser als nichts (selbst wenn nichts nicht nichts ist, nicht?)
            '    'If Not AnimPeriode = 1 Then
            '    '    'Das hat zumindest nicht nur mit der Defekten Periode zu tun!
            '    '    CInt("Hallo").ToString()
            '    'End If
            'End If

            Grafikengine.Grafikkarte.Transform.World = standardMatrix
        End If
    End Sub
    Public Shared Function getEinheit(ByVal EinheitID As String) As EinheitInstanz
        For i = 0 To Einheiten.Length - 1
            If Einheiten(i).EinheitID.ToUpper = EinheitID.ToUpper Then
                'If Einheiten(i).Kaputt Then
                '    'Kaputt? dann machen wir halt ein neues!
                '    Dim Dat As String = Einheiten(i).Dateiname
                '    Einheiten(i) = New EinheitInstanz
                '    Einheiten(i).Dateiname = Dat
                '    Einheiten(i).EinheitID = Dat.Remove(0, Dat.LastIndexOf("\") + 1).ToUpper.Replace(".X".ToUpper, "")
                '    Einheiten(i).Mesh = New Objekt3DAnim()
                '    Einheiten(i).Mesh.MeshBildLaden(Dat)
                ' Einheiten(i).Kaputt = False
                'End If
                If Not Einheiten(i).Kaputt Then Return Einheiten(i)
            End If
        Next
        ' Console.WriteLine("folgendes EinheitenMesh fehlt: " + EinheitID)
        If NichtEinheit IsNot Nothing Then
            If NichtEinheit.Mesh IsNot Nothing Then
                'Auch wenn es die einheit nicht gibt, gibt es zumindest die Einheit, die es nicht gibt! ist doch schonmal immerhin etwas.
                Return NichtEinheit
            End If
        End If
        Return Nothing 'nichtmal die nichtvorhandene Einheit gibt's na so was!
    End Function
    Public Function getMesh(ByVal EinheitID As String) As Mesh
        For i = 0 To Einheiten.Length - 1
            If Einheiten(i).EinheitID.ToUpper = EinheitID.ToUpper Then
                Return Einheiten(i).Mesh.MeshBild.moMesh 'das moMesh, wird aber nicht gesetzt, weil es ja eine Animation ist!
            End If
        Next
        Return Nothing
    End Function
End Class
